#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

typedef struct{
    size_t *data;
    size_t size;
    size_t len;
}Vector;

size_t vec_expand(Vector *vec);

Vector *vec_init(size_t n)
{
    Vector *vec = (Vector *)malloc(sizeof(Vector));
    vec->data = (size_t *)malloc(sizeof(size_t) * n);
    vec->size = n;
    vec->len = 0;

    printf("init successfully, size is %ld\n", n);
    return vec;
}

void vec_free(Vector * vec)
{
    if(!vec)
        return;
    
    free(vec->data);
    free(vec);
}

size_t vec_insert(Vector *vec, size_t idx, size_t value)
{
    size_t ret = 0;

    if (!vec)
        return ret;
    
    if (idx < 0 || idx > vec->len)
        return ret;
    
    if (vec->len == vec->size)
    {
        if (!vec_expand(vec))
        {
            return 0;
        }
    }

    memcpy(&vec->data[idx + 1], &vec->data[idx], (vec->len - idx) * sizeof(size_t));
    vec->data[idx] = value;
    vec->len++;
    ret = 1;

    return ret;
}

size_t vec_delete(Vector *vec, size_t idx)
{

    if (!vec)
        return 0;
    
    if (idx < 0 || idx > vec->len - 1)
        return 0;
    if (vec->len == 0)
        return 0;

    memcpy(&vec->data[idx], &vec->data[idx + 1], (vec->len - idx - 1) * sizeof(size_t));
    vec->len--;
    
    return 1;
}
void show_vector_data(Vector *vec)
{
    int i = 0;
    if (!vec)
    {
        printf("Err: vec is NULL.\n");
        return;
    }

    printf("Vec:[");
    for (i = 0; i < vec->len; i++)
    {
        i && printf(",");
        printf("%ld", vec->data[i]);
    }
    
    printf("]\n");

}

size_t vec_expand(Vector *vec)
{
    if (!vec)
        return 0;
    
    size_t expsize = vec->size;
    size_t *tmp;
    
    while (expsize)
    {
        tmp = (size_t *)realloc(vec->data, sizeof(size_t)*(vec->size + expsize)); 
        
        if (tmp)
            break;
        
        expsize >>= 2;
    }
    
    if (!tmp)
    {
        printf("expand failed!\n");
        return 0;
    }

    vec->data = tmp;
    vec->size += expsize; 
    
    printf("expand successfully!\n");

    return 1;
}

int main(void)
{
    Vector *vec = vec_init(1);
    srand(time(0));

    int cnt = 20;
    while (cnt--)
    {
        size_t val = rand() % 100;
        size_t op = rand() % 4;
        size_t idx = rand() % (vec->len + 3) - 1;

        // printf("op %ld, val %ld, idx%ld .\n", op, val, idx);
        switch (op)
        {
        case 0:
        case 1:
        case 2:
            printf("insert %ld at %ld, res = %ld.\n", val, idx, vec_insert(vec, idx, val));
            break;
        case 3:
            printf("delete at %ld, res = %ld.\n", idx, vec_delete(vec, idx));
            break;
        default:
            break;
        }

        show_vector_data(vec);
    }
    
    vec_free(vec);
    return 0;
}